package com.edroid.swingtest;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import javax.swing.JTextPane;
import javax.swing.SwingUtilities;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;

public class ClientSide extends SimpleChannelHandler {
	ChannelFuture future;
	Channel mChannel;
	JTextPane textPane;
	

	public ClientSide(JTextPane textPane) {
		this.textPane = textPane;
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				start();
			}
		}).start();
	}
	
	public void start() {
		
		// 创建客户端channel的辅助类,发起connection请求
		ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));

		// It means one same HelloWorldClientHandler instance is going to handle
		// multiple Channels and consequently the data will be corrupted.
		// 基于上面这个描述，必须用到ChannelPipelineFactory每次创建一个pipeline
		bootstrap.setPipelineFactory(new ChannelPipelineFactory() {

			@Override
			public ChannelPipeline getPipeline() {
				ChannelPipeline pipeline = Channels.pipeline();
				pipeline.addLast("decoder", new StringDecoder());
				pipeline.addLast("encoder", new StringEncoder());
				pipeline.addLast("handler", ClientSide.this);

				return pipeline;
			}
		});

		// 创建无连接传输channel的辅助类(UDP),包括client和server
		future = bootstrap.connect(new InetSocketAddress("localhost", 8099));
//		future.getChannel().getCloseFuture().awaitUninterruptibly();
//		
//		bootstrap.releaseExternalResources();
//		
//		mChannel = future.getChannel();
	}
	
	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
		super.channelConnected(ctx, e);
		
		System.out.println("Client:" + "channelConnected");
		
		e.getChannel().write("Hello");
		
		mChannel = e.getChannel();
	}

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
		final String message = (String) e.getMessage();
		
		System.out.println("Client:" + message);
		
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				textPane.setText(message);
			}
		});
		
//		e.getChannel().close();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
		// TODO Auto-generated method stub
		super.exceptionCaught(ctx, e);
	}
	
	public void send(String msg) {
		future.getChannel().write(msg);
	}
}
